﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace SPWebShell
{
    /// <summary>
    /// All extension methods are defined here.
    /// </summary>
    public static class Extensions
    {
        public static string ConvertToViewFields(this string[] fields)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string field in fields)
            {
                sb.AppendFormat("<FieldRef Name='{0}' />", field);
            }
            return sb.ToString();
        }
        /// <summary>
        /// Returns the value of the specified attribute. The prefix ows_ is prefixed inside the method
        /// Rationale - SP web services do not return a column if there is blank value. 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="spattributename"></param>
        /// <returns></returns>
        public static string SafeGetXmlAttribute(this System.Xml.XmlNode node, string spattributename)
        {
            string fullSPAttributeName = spattributename.SharePointWebFieldName();
            System.Xml.XmlAttribute attrib = node.Attributes[fullSPAttributeName];
            if (attrib == null) return "";
            string value = node.Attributes[fullSPAttributeName].Value;
            return value;
        }
        /// <summary>
        /// For attributes which include the ID delimited by a hash, the ID is stripped off
        /// e.g. 1;#helloworld will give helloworld
        /// </summary>
        /// <param name="node"></param>
        /// <param name="spattributename"></param>
        /// <returns></returns>
        public static string SafeGetXmlAttributeRemoveID(this System.Xml.XmlNode node, string spattributename)
        {
            int spid = node.SafeGetXmlAttribute("ID").ToInt();
            string fullValue = node.SafeGetXmlAttribute(spattributename);
            string actualvalue=fullValue.Substring((spid.ToString() + ";#").Length);
            return actualvalue;
        }

        public static Int32 ToInt(this string input)
        {
            Int32 output;
            bool retval = Int32.TryParse(input, out output);
            if (!retval)
            {
                string message = string.Format("Could not parse '{0}' into Int32", input);
                Trace.TraceError(message);
                throw new Exception(message);
            }
            else
                return output;
        }
        public static DateTime ToDate(this string input)
        {
            DateTime output;
            bool retval = DateTime.TryParse(input, out output);
            if (!retval)
            {
                string message = string.Format("Could not parse '{0}' into DateTime", input);
                Trace.TraceError(message);
                throw new Exception(message);
            }
            else
                return output;
        }
        /// <summary>
        /// Rationale - useful for covnerting SP list columns to Web service fields
        /// </summary>
        /// <param name="listfieldName"></param>
        /// <returns></returns>
        public static string SharePointWebFieldName(this string listfieldName)
        {
            return "ows_" + listfieldName;
        }
        public static bool IsSPError(this XmlNode xmlNodeResults, out string errorMessage)
        {
            /*
            <Results xmlns="http://schemas.microsoft.com/sharepoint/soap/"><Result ID="1,New"><ErrorCode>0x81020014</ErrorCode><ErrorText>One or more field types are not installed properly. Go to the list settings page to delete these fields.</ErrorText></Result></Results>             
             */
            string xmlresults = xmlNodeResults.OuterXml;
            errorMessage = "";
            if (xmlresults.Contains("<ErrorCode>0x00000000</ErrorCode>"))
            {
                errorMessage = "";
                return false;
            }
            if (xmlresults.Contains("<ErrorCode>"))
            {
                //<ErrorText>.{1,}</ErrorText>
                Regex r = new Regex(@"<ErrorText>(.|\n)*</ErrorText>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                Match m = r.Match(xmlresults);
                if (m.Success) errorMessage = m.ToString();
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Converts a XML node returned GetListItems into a POCO object instance
        /// </summary>
        /// <param name="ndRow"></param>
        /// <returns></returns>
        public static SPDoclibItem NodeToDoclibItem(this XmlNode ndRow)
        {
            SPDoclibItem item = new SPDoclibItem();
            item.SPID = ndRow.SafeGetXmlAttribute("ID").ToInt();
            string fileLeafRef = ndRow.SafeGetXmlAttribute("FileLeafRef");
            item.Name = fileLeafRef.Substring((item.SPID.ToString() + ";#").Length);
            item.Created = ndRow.SafeGetXmlAttribute("Created").ToDate();
            item.Modified = ndRow.SafeGetXmlAttribute("Modified").ToDate();

            string objtype = ndRow.SafeGetXmlAttribute("FSObjType").Substring((item.SPID.ToString() + ";#").Length);
            item.IsFolder = (objtype == "1") ? true : false;
            item.CreatedBy = "";
            if (item.IsFolder)
            {
                item.FileSize = 0;
            }
            else
            {
                item.FileSize = ndRow.SafeGetXmlAttribute(Constants.FIELD_FILESIZE).Substring((item.SPID.ToString() + ";#").Length).ToInt();
            }
            item.ModifiedBy = "";
            item.RelativeUrl = "";//TODO
            item.ServerRelativeUrl = ndRow.SafeGetXmlAttribute("FileRef").Substring((item.SPID.ToString() + ";#").Length);
            item.Title = ndRow.SafeGetXmlAttribute(Constants.FIELD_TITLE);
            item.AbsoluteUrl = ndRow.SafeGetXmlAttribute(Constants.FIELD_ENCODEDABSURL);
            return item;
        }
        public static entity.SPList NodeToSPList(this XmlNode ndListInfo)
        {
            XmlNamespaceManager ns = new XmlNamespaceManager(ndListInfo.OwnerDocument.NameTable);
            ns.AddNamespace("z", "http://schemas.microsoft.com/sharepoint/soap/");
            XmlNode ndFields = ndListInfo.SelectSingleNode(".//z:Fields", ns);
            List<entity.SPField> fields = new List<entity.SPField>();
            foreach (XmlNode ndField in ndFields.ChildNodes)
            {
                entity.SPField field = new entity.SPField(ndField);
                fields.Add(field);
            }

            entity.SPList listinfo = new entity.SPList(ndListInfo);
            listinfo.Fields = fields.ToArray();
            return listinfo;
        }
        public static entity.SPPermissionMask IntToMask(int mask)
        {
            Type t = typeof(entity.SPPermissionMask);
            var valuesAsArray = Enum.GetValues(typeof(entity.SPPermissionMask));
            entity.SPPermissionMask maskFinal=0;
            foreach (entity.SPPermissionMask emask in valuesAsArray)
            {
                if ((mask &  (int)emask) > 0)
                {
                    maskFinal = maskFinal | emask;
                }
            }
            return maskFinal;
        }
    }
}
